﻿using System;
using MySql.Simple.Mapper.Finders;
using MySql.Simple.Mapper.Structures;

namespace MySql.Simple.Mapper.Commands.Rows
{
    /// <summary>
    /// Reads the contents of a SQL table row into a given object type.
    /// </summary>
    public static class SelectOneCommand
    {
        #region SQL

        private const string Sql = @"SELECT {0} FROM {1} WHERE {2} = {3};";

        #endregion

        /// <summary>
        /// Reads the contents of a SQL table row into a given object type.
        /// </summary>
        /// <returns></returns>
        public static T Execute<T>(object id, Connection connection) where T : new()
        {
            var result = default(T);

            // Execute command
            using (var db = connection.Open())
            {
                using (var command = db.CreateCommand())
                {
                    // Get SQL ingredients
                    var tableName = TableNameFinder.Find(typeof(T));

                    // Get columns
                    var columns = ColumnFinder.Find(typeof(T));

                    // ensure PK is set
                    if (columns.HasPrimaryKey)
                        throw new ApplicationException("Primary key has not been set on " + typeof(T).Name);

                    // build SQL statement
                    var sql = string.Format(Sql, columns.ToSelectColumnsSql(), tableName, columns.PrimaryKeyName, id);

                    command.CommandText = string.Format(sql, id);

                    // Execute!
                    using (var reader = command.ExecuteReader())
                    {
                        // Bind results 
                        if (reader.Read()) result = DataReaderBinder.Bind<T>(reader);
                    }
                }
            }

            return result;
        }  
    }
}